home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Online / opennap / remove_connection.c < prev    next >
C/C++ Source or Header  |  2001-06-08  |  5KB  |  178 lines

  1. /* Copyright (C) 2000-1 drscholl@users.sourceforge.net
  2.    This is free software distributed under the terms of the
  3.    GNU Public License.  See the file COPYING for details.
  4.  
  5.    $Id: remove_connection.c,v 1.58 2001/02/15 08:39:45 drscholl Exp $ */
  6.  
  7. #include <string.h>
  8. #ifndef WIN32
  9. #include <unistd.h>
  10. #endif
  11. #include <stdlib.h>
  12. #include "opennap.h"
  13. #include "hashlist.h"
  14. #include "debug.h"
  15.  
  16. static void
  17. server_split (USER * user, CONNECTION * con)
  18. {
  19.     ASSERT (validate_user (user));
  20.     ASSERT (validate_connection (con));
  21.     ASSERT (con->class == CLASS_SERVER);
  22.  
  23.     /* check to see if this user was behind the server that just split */
  24.     if (user->con == con)
  25.     {
  26.     /* on split, we have to notify our peer servers that this user
  27.        is no longer online */
  28.     pass_message_args (con, MSG_CLIENT_QUIT, "%s", user->nick);
  29.     /* remove the user from the hash table */
  30.     hash_remove (Users, user->nick);
  31.     }
  32. }
  33.  
  34. /* free resources associated with CLASS_USER connection. this is broken out
  35.    here so that login() can call this directly to remove a "ghost" user and
  36.    allow the new connection to complete. */
  37. void
  38. remove_user (CONNECTION * con)
  39. {
  40.     LIST   *u;
  41.  
  42.     ASSERT (ISUSER (con));
  43.  
  44.     if (con->user->level >= LEVEL_MODERATOR)
  45.     Mods = list_delete (Mods, con);
  46.  
  47.     /* remove user from global list, calls free_user() indirectly */
  48.     ASSERT (validate_user (con->user));
  49.     hash_remove (Users, con->user->nick);
  50.  
  51.     /* if this user had hotlist entries, remove them from the lists */
  52.     for (u = con->uopt->hotlist; u; u = u->next)
  53.     {
  54.     ASSERT (hashlist_validate (u->data));
  55.     hashlist_remove (Hotlist, ((hashlist_t *) u->data)->key, con);
  56.     }
  57.  
  58.     list_free (con->uopt->hotlist, 0);
  59.     list_free (con->uopt->ignore, free_pointer);
  60.  
  61.     if (con->uopt->files)
  62.     {
  63.     /* indirectly calls free_datum() */
  64.     free_hash (con->uopt->files);
  65.     }
  66.  
  67.     /* sanity check */
  68.     if (con->uopt->searches < 0)
  69.     log("remove_user: ERROR, con->uopt->searches < 0!!!");
  70.  
  71.     FREE (con->uopt);
  72. }
  73.  
  74. static void
  75. free_server_name (const char *s)
  76. {
  77.     LIST  **list = &Server_Names;
  78.     LIST   *tmp;
  79.  
  80.     for (; *list; list = &(*list)->next)
  81.     {
  82.     if (s == (*list)->data)
  83.     {
  84.         tmp = *list;
  85.         *list = (*list)->next;
  86.         FREE (tmp->data);
  87.         FREE (tmp);
  88.         break;
  89.     }
  90.     }
  91. }
  92.  
  93. void
  94. remove_connection (CONNECTION * con)
  95. {
  96.     ASSERT (validate_connection (con));
  97.  
  98.     /* should have been properly shut down */
  99.     if (con->fd != -1)
  100.     log ("remove_connection: ERROR, con->fd != -1");
  101.  
  102.     /* if this connection had any pending searches, cancel them */
  103.     cancel_search (con);
  104.  
  105.     if (ISUSER (con))
  106.     {
  107.     remove_user (con);
  108.     }
  109.     else if (ISSERVER (con))
  110.     {
  111.     /* if we detect that a server has quit, we need to remove all users
  112.        that were behind this server.  we do this by searching the User
  113.        hash table for entries where the .serv member is this connection.
  114.        we also need to send QUIT messages for each user to any other
  115.        servers we have */
  116.  
  117.     /* first off, lets remove this server from the Servers list so
  118.        that pass_message() doesnt try to send message back through this
  119.        server (although we could just pass this connection to it and it
  120.        would avoid sending it) */
  121.  
  122.     log ("remove_connection: server split detected (%s)", con->host);
  123.     if (!con->quit)
  124.     {
  125.         notify_mods (SERVERLOG_MODE, "Server %s has quit: EOF",
  126.              con->host);
  127.         /* notify our peers this server has quit */
  128.         pass_message_args (con, MSG_CLIENT_DISCONNECT,
  129.                    ":%s %s \"EOF\"", Server_Name, con->host);
  130.  
  131.         /* if this server was linked to other servers, remove the
  132.          * information we have on those links */
  133.         remove_links (con->host);
  134.     }
  135.  
  136.     Servers = list_delete (Servers, con);
  137.  
  138.     /* remove all users that were behind this server from the hash table.
  139.        this should be an infrequent enough occurance than iterating the
  140.        entire hash table does not need to be optimized the way we split
  141.        out the server connections. */
  142.     hash_foreach (Users, (hash_callback_t) server_split, con);
  143.  
  144.     finalize_compress (con->sopt);
  145.     buffer_free (con->sopt->outbuf);
  146.     FREE (con->sopt);
  147.  
  148.     /* free the server name cache entry */
  149.     free_server_name (con->host);
  150.     }
  151.     else
  152.     {
  153.     ASSERT (con->class == CLASS_UNKNOWN);
  154.     if (con->server_login)
  155.     {
  156.         if (con->opt.auth)
  157.         {
  158.         if (con->opt.auth->nonce)
  159.             FREE (con->opt.auth->nonce);
  160.         if (con->opt.auth->sendernonce)
  161.             FREE (con->opt.auth->sendernonce);
  162.         FREE (con->opt.auth);
  163.         }
  164.     }
  165.     }
  166.  
  167.     /* common data */
  168.     if (con->host)
  169.     FREE (con->host);
  170.     buffer_free (con->sendbuf);
  171.     buffer_free (con->recvbuf);
  172.  
  173.     /* temp fix to catch bad contexts */
  174.     memset (con, 0xff, sizeof (CONNECTION));
  175.  
  176.     FREE (con);
  177. }
  178.